package com.magold.logic.region.airflow;

import org.andengine.engine.camera.Camera;
import org.andengine.entity.particle.Particle;
import org.andengine.entity.particle.ParticleSystem;
import org.andengine.entity.particle.initializer.IParticleInitializer;
import org.andengine.entity.particle.modifier.AlphaParticleModifier;
import org.andengine.entity.particle.modifier.ColorParticleModifier;
import org.andengine.entity.particle.modifier.ExpireParticleInitializer;
import org.andengine.entity.shape.IAreaShape;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.extension.physics.box2d.util.constants.PhysicsConstants;

import android.opengl.GLES20;

import com.magold.logic.LogicComponentFinder;
import com.magold.physics.MagoldPhysicsConnector;
import com.magold.sprite.IMultiTextureSprite;


public class AirflowParticleSystem extends ParticleSystem<IMultiTextureSprite> {
	private final AirflowParticleFactory mFactory;
	
	public AirflowParticleSystem(
			AirflowParticleFactory pEntityFactory,
			AirflowParticleEmitter pParticleEmitter, float pMinRate, float pMaxRate, int pParticlesMaximum) {
		super(pEntityFactory, pParticleEmitter, pMinRate, pMaxRate, pParticlesMaximum);
		mFactory = pEntityFactory;
	}
	
	public void setPhysicsWorld(PhysicsWorld pWorld) {
		mFactory.setPhysicesWorld(pWorld);
	}

	public static AirflowParticleSystem create(AirflowRegion pRegion, float pSpeedInPixel, Camera pCamera) {
		IAreaShape pRangeShape = pRegion.getRangeShape();
		float speedInMeter = (pSpeedInPixel / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);	// m/s;
		float lifetime = pRangeShape.getHeight() / pSpeedInPixel;
						
		AirflowParticleRecycleHandler recycleHandler = new AirflowParticleRecycleHandler(pCamera);
		AirflowParticleFactory pFactory = new AirflowParticleFactory(pRangeShape, recycleHandler);
		AirflowParticleEmitter emitter = new AirflowParticleEmitter(pRangeShape, pFactory.getParticleWidth());
		
		float ratePerCol = 1 / (pFactory.getParticleHeight() / pSpeedInPixel);
		float colCount = pRangeShape.getWidth() / pFactory.getParticleWidth();
		float rowCount = pRangeShape.getHeight() / pFactory.getParticleHeight();
		float rate = ratePerCol * colCount;
		
		AirflowParticleSystem system = new AirflowParticleSystem(pFactory, emitter, rate*0.9f, rate*1.1f, (int) (rowCount*colCount));
		
		system.addParticleInitializer(new ApplyPhysicsInitializer(speedInMeter, pRangeShape));
		system.addParticleInitializer(new ExpireParticleInitializer<IMultiTextureSprite>(lifetime*1.1f));
		system.addParticleInitializer(new IParticleInitializer<IMultiTextureSprite>() {
			@Override
			public void onInitializeParticle(Particle<IMultiTextureSprite> pParticle) {
				IMultiTextureSprite sprite = pParticle.getEntity();
				sprite.setBlendingEnabled(true);
				sprite.setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
			}
		});
		
		system.addParticleModifier(recycleHandler);
		system.addParticleModifier(new AlphaParticleModifier<IMultiTextureSprite>(0, 0.8f, 0.1f, 1));
		system.addParticleModifier(new AlphaParticleModifier<IMultiTextureSprite>(Math.max(0.8f, lifetime-0.8f), lifetime, 1, 0));
		system.addParticleModifier(new ColorParticleModifier<IMultiTextureSprite>(0, lifetime, 1, 1, 1, 0.3f, 1, 0.3f));
		
		return system;
	}

	public void destroy(PhysicsWorld pWorld) {
		for (Particle<IMultiTextureSprite> particle : mParticles) {
			if(particle == null) break;
			IMultiTextureSprite sprite = particle.getEntity();
			MagoldPhysicsConnector connector = LogicComponentFinder.findConnector(sprite);
			if (connector != null) {
				pWorld.unregisterPhysicsConnector(connector);
				pWorld.destroyBody(connector.getBody());
			}
		}
	}
}
